package stubcall

import (
	"gitee.com/CloudGuan/rpc-go-backend/idlrpc/protocol"
)

//@title 客户端调用远程调用过程存根
type ClientStubCall struct {
	callID    uint32 //调用id
	stubID    uint32 //关联到的stub
	method    uint32 //调用的方法id
	errorCode uint32 //RPC 回复的错误码
	retryTime uint32 //重试次数
	timeout   uint32 //超时时间
	sendpkg   []byte //发送包缓存用于断线重连
	recvChan  chan *protocol.ResponsePackage
}

func NewClientStubCall(stubID, retry, timeout uint32) *ClientStubCall {
	cstubcall := &ClientStubCall{
		stubID:    stubID,
		errorCode: protocol.IDL_SERVICE_ERROR,
		retryTime: retry,
		timeout:   timeout,
		recvChan:  make(chan *protocol.ResponsePackage, 1),
	}
	return cstubcall
}

func (cs *ClientStubCall) GetCallID() uint32 {
	return cs.callID
}

//获取client stub
func (cs *ClientStubCall) GetStubID() uint32 {
	return cs.stubID
}

func (cs *ClientStubCall) GetErrorCode() uint32 {
	return cs.errorCode
}

func (cs *ClientStubCall) SetErrorCode(code uint32) {
	cs.errorCode = code
}

//@title 减少重试次数
func (cs *ClientStubCall) DecrRetryTime() {
	if cs.retryTime > 0 {
		cs.retryTime--
	}
}

//@title 获取超时时间 单位毫秒
func (cs *ClientStubCall) GetTimeOut() uint32 {
	if cs.timeout == 0 {
		return 5000
	} else {
		return cs.timeout
	}
}

func (cs *ClientStubCall) GetRetryTime() uint32 {
	return cs.retryTime
}

func (cs *ClientStubCall) GetSendData() []byte {
	return cs.sendpkg[:]
}

func (cs *ClientStubCall) SetSendData(pkg []byte) {
	cs.sendpkg = pkg
}

func (cs *ClientStubCall) SetMethodId(method uint32) {
	cs.method = method
}

func (cs *ClientStubCall) GetMethodId() uint32 {
	return cs.method
}

//@title
//@detail 这里我对于我的代码有疑问我是通过接口唤醒相关的stub 这里似乎并不需要持有实现接口？
//但是我应该怎么做才能唤醒我对应的代码那？ 通过chan 唤醒阻塞的协程
func (cs *ClientStubCall) Ret(resp *protocol.ResponsePackage) {
	cs.recvChan <- resp
}

func (cs *ClientStubCall) Done() <-chan *protocol.ResponsePackage {
	return cs.recvChan
}
